package models;

import play.*;
import play.data.validation.Unique;
import play.db.jpa.*;

import javax.persistence.*;

import java.lang.reflect.Array;
import java.util.*;

import java.util.LinkedList;

@Entity
/***
 * this is class exercise which is created for a certain tutorial
 * @author hadeer
 *
 */
public class Exercise extends Model {

	public long Exerciseid;
	public long CreatorID;
	public boolean isPublished;
	public boolean isRejected;
	public boolean isRandom;
	public int TotalScore = 0;// samar this is the total score for the exercise
	int score = 0; // this is the score that the user will get at each exercise

	public int exerciseScore = 0;
	@Unique
	public String ExerciseName;

	@ElementCollection
	public List<Integer> scores;

	@ManyToMany(mappedBy = "exerciseTaken", cascade = CascadeType.ALL)
	public List<RegisteredUser> peopleAnswered;

	@ManyToOne
	@JoinColumn(name = "exercise_score")
	public RegisteredUser scoress;

	public String comment;
	@ManyToOne
	@JoinTable(name = "exerciseInTutorials")
	public Tutorial myTut;

	@OneToMany(mappedBy = "myExercise", cascade = CascadeType.ALL)
	public List<Question> questions;

	// Start Mayar
	@ManyToMany(mappedBy = "recommendListExercise", cascade = CascadeType.ALL)
	public List<CommunityList> recommendExercises;

	// End Mayar

	public Exercise(long cid, long tutid, String ename) {

		this.ExerciseName = ename;
		this.CreatorID = cid;
		this.myTut = Tutorial.findById(tutid);
		this.isPublished = false;
		this.isRejected = false;
		this.isRandom = false;
		this.peopleAnswered = new ArrayList<RegisteredUser>();

		this.questions = new ArrayList<Question>();
		// Start Mayar
		this.recommendExercises = new ArrayList<CommunityList>();
		this.save();
		// End Mayar
	}

	/***
	 * this method adds question to a certain exercise
	 * 
	 * @author hadeer
	 * @param eid
	 * @param quest
	 * @param marks
	 * @param Listchoices
	 */
	public void addQuestion(long eid, String quest, int marks,
			List<Choice> Listchoices) {

		Question tempQuestion = new Question(quest, marks, eid);
		Exercise CurrentExercise = Exercise.findById(eid);
		for (int i = 0; i < Listchoices.size(); i++) {
			tempQuestion.getMyChoices().add(Listchoices.get(i));
		}
		CurrentExercise.questions.add(tempQuestion);

	}

	public List<Question> getQuestions() {
		return questions;
	}

	public void setQuestions(List<Question> questions) {
		this.questions = questions;
	}

	/***
	 * @author dana To get the Exercise from the DB
	 * @param exerciseId
	 * @return The instance of Exercise
	 */
	public Exercise getExercise(long exerciseId) {
		return Exercise.findById(exerciseId);

	}

	/***
	 * @author dana This method returns the value of isPublished
	 * @return
	 */
	public boolean isPublished() {
		return isPublished;
	}

	/***
	 * @author dana This method changes the variable isPublished
	 * @param isPublished
	 */
	public void setPublished(boolean isPublished) {
		this.isPublished = isPublished;
	}

	/***
	 * @author dana This method returns the value of isRejected
	 * @return
	 */
	public boolean isRejected() {
		return isRejected;
	}

	/***
	 * @author dana This method changes the variable isRejected
	 */
	public void setRejected(boolean isRejected) {
		this.isRejected = isRejected;
	}

	/***
	 * @author dana This method returns the value of isRandom
	 * @return
	 */
	public boolean isRandom() {
		return isRandom;
	}

	/***
	 * @author dana This method changes the variable isRandom
	 * @param isRandom
	 */
	public void setRandom(boolean isRandom) {
		this.isRandom = isRandom;
		this.save();
	}

	/***
	 * @This method calculates total score for the exercise
	 * @author samar
	 * @param long exerciseid
	 */

	public int sumOfmarks(long exerciseid) {

		Exercise exercise = Exercise.findById(id);
		List<Question> question = exercise.getQuestions();
		int x = exercise.getTotalScore();
		for (int i = 0; i <= question.size(); i++) {

			if (i == question.size()) {
				exercise.setTotalScore(0);
				exercise.save();
				return x;
			}
			x += question.get(i).getMarks();
			exercise.setTotalScore(x);
			exercise.save();

		}
		return x;
	}

	/***
	 * @This method gets the total score for the exercise
	 * @author samar
	 * @param
	 */

	public int getTotalScore() {
		return TotalScore;
	}

	/***
	 * @This method set the total score for the exercise
	 * @author samar
	 * @param int total score
	 */

	public void setTotalScore(int totalScore) {
		TotalScore = totalScore;
	}

	/***
	 * @This method gets the score for every user after taking the exercise
	 * @author samar
	 * @param
	 */

	public int getScore() {
		return score;
	}

	/***
	 * @This method sets the score for every user after taking the exercise
	 * @author samar
	 * @param int score
	 */

	public void setScore(int score) {
		this.score = score;
	}

	/***
	 * this method returns the list of peopleanswered of a certain exercise
	 * 
	 * @author hadeer
	 * @return
	 */
	public List<RegisteredUser> getPeopleAnswered() {
		return peopleAnswered;
	}

	/***
	 * this method sets the list of people answered to the gived list
	 * 
	 * @author hadeer
	 * @param peopleAnswered
	 */
	public void setPeopleAnswered(List<RegisteredUser> peopleAnswered) {
		this.peopleAnswered = peopleAnswered;
	}

	/***
	 * this method returns the list of scores of the exercise
	 * 
	 * @author hadeer
	 * @return
	 */
	public List<Integer> getScores() {
		return scores;
	}

	/***
	 * this methods sets the list of scores to the given list
	 * 
	 * @param scores
	 */
	public void setScores(List<Integer> scores) {
		this.scores = scores;
	}

	/***
	 * this method returns the exercisename
	 * 
	 * @author hadeer
	 * @return
	 */
	public String getExerciseName() {
		return ExerciseName;
	}

	/***
	 * this method sets the exercise name with the given name
	 * 
	 * @author hadeer
	 * @param exerciseName
	 */
	public void setExerciseName(String exerciseName) {
		ExerciseName = exerciseName;
	}

	/***
	 * this method returns the exercise id
	 * 
	 * @author hadeer
	 * @return
	 */
	public long getExerciseid() {
		return Exerciseid;
	}

	/***
	 * this method sets the exercise id with the gived id
	 * 
	 * @author hadeer
	 * @param exerciseid
	 */
	public void setExerciseid(long exerciseid) {
		Exerciseid = exerciseid;
	}

	/***
	 * this method returns the id of the creator
	 * 
	 * @author hadeer
	 * @return
	 */
	public long getCreatorID() {
		return CreatorID;
	}

	/***
	 * this method sets the creator id with the given id
	 * 
	 * @author hadeer
	 * @param creatorID
	 */
	public void setCreatorID(long creatorID) {
		CreatorID = creatorID;
	}

	/***
	 * this method returns the scoress of the exercise
	 * 
	 * @author hadeer
	 * @return
	 */
	public RegisteredUser getScoress() {
		return scoress;
	}

	/***
	 * this method sets the scoress of the exercise
	 * 
	 * @author hadeer
	 * @param scoress
	 */
	public void setScoress(RegisteredUser scoress) {
		this.scoress = scoress;
	}

	/***
	 * this method returns the comment
	 * 
	 * @author hadeer
	 * @return
	 */
	public String getComment() {
		return comment;
	}

	/***
	 * this method sets the comment of the exercise
	 * 
	 * @author hadeer
	 * @param comment
	 */
	public void setComment(String comment) {
		this.comment = comment;
	}

	/***
	 * this method return the tutorial of this exercise
	 * 
	 * @author hadeer
	 * @return
	 */
	public Tutorial getMyTut() {
		return myTut;
	}

	/***
	 * this method sets the tutorial of the exercise
	 * 
	 * @param myTut
	 */
	public void setMyTut(Tutorial myTut) {
		this.myTut = myTut;
	}

	public List<CommunityList> getRecommendExercises() {
		return recommendExercises;
	}

	public void setRecommendExercises(List<CommunityList> recommendExercises) {
		this.recommendExercises = recommendExercises;
	}

	public int getExerciseScore() {
		return exerciseScore;
	}

	public void setExerciseScore(int exerciseScore) {
		this.exerciseScore = exerciseScore;
	}

}
